package com.nsharmon.dao.entity;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToOne;
import javax.persistence.Transient;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.nsharmon.l18n.L18n;
import com.nsharmon.webapp.listeners.HibernateSessionListener;

@Entity
@DiscriminatorValue("condition")
public class ConditionAxiom extends Axiom {
	private Condition condition;
	private Axiom axiom;
	
	public enum ConditionVariant {
		Default
	}
	
	public ConditionAxiom() {
		setVariant(ConditionVariant.Default);
	}
	
	@OneToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
	public Condition getCondition() {
		return condition;
	}

	public void setCondition(Condition condition) {
		this.condition = condition;
	}

	@OneToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
	public Axiom getAxiom() {
		return axiom;
	}

	public void setAxiom(Axiom axiom) {
		this.axiom = axiom;
	}

	@Transient
	public String toString() {
		return toString(getVariant());
	}
	
	@Override
	@Transient
	public Axiom clone() {
		ConditionAxiom clone = (ConditionAxiom)super.clone();
		
		clone.setAxiom(getAxiom().clone());
		clone.setCondition(getCondition().clone());
		return clone;
	}
	
	@Override
	@Transient	
	public void replace(EntityObject eo, EntityObject eo2) {
		super.replace(eo, eo2);
		
		getCondition().replace(eo, eo2);
		getAxiom().replace(eo,  eo2);
	}

	@Transient
	public String toString(Enum<?> variant) {
		return L18n.getMessage(getClass(), variant.toString(), getCondition(), getAxiom());
	}	
	
	@Transient
	public static ConditionAxiom ifThen(Project project, Condition condition, Axiom axiom, ConditionVariant variant) {
		return ifThen(null, project, condition, axiom, variant);
	}
	
	@Transient
	public static ConditionAxiom ifThen(Session session, Project project, Condition condition, Axiom thenAxiom, ConditionVariant variant) {
		ConditionAxiom axiom = null;
		boolean localSession = false;
		Transaction trx = null;
		if(session == null) {
			localSession = true;
			session = HibernateSessionListener.openSession();
			trx = session.beginTransaction();
		}
		
		try {
			axiom = new ConditionAxiom();
			axiom.setProject(project);
			axiom.setVariant(variant);
			project.getAxioms().add(axiom);
			
			axiom.setCondition(condition);
			axiom.setAxiom(thenAxiom);
			
			session.update(project);
			
			if(localSession) {
				trx.commit();
			}
		} catch(HibernateException e) {
			axiom = null;
			
			if(localSession) {
				trx.rollback();
			}
			throw e;
		} finally {
			if(localSession) {
				session.close();
			}
		}
		return axiom;			
	}	
}
